﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Management.Automation;

namespace pshcli
{
    [Cmdlet("Plot", "Results")]
    public class PSH_PlotDwarf: Cmdlet
    {
        private string resultsfilename;
        private Dwarf dwarf;
        private int reset;
        private String what;

        [Parameter(
            Position= 0,
            ValueFromPipeline = true,
            Mandatory = false,
            HelpMessage = "Specify path to results xls file")]
        public string ResultsFile
        {
            get { return resultsfilename; }
            set { resultsfilename = value; }
        }

        [Parameter(
            Position = 1,
            ValueFromPipeline = true,
            Mandatory = false,
            HelpMessage = "Dwarf object to be executed")]
        public Dwarf Dwarf
        {
            get { return dwarf; }
            set { dwarf = value; }
        }

        //Switchparameter; != 0 to clear
        [Parameter(
            Position = 2,
            ValueFromPipeline = true,
            Mandatory = false,
            HelpMessage = "Clear xls file. Parameter != 0 to clear.")]
        public int Clear
        {
            get { return reset; }
            set { reset = value; }
        }


        //Switchparameter; != 0 to clear
        [Parameter(
            Position = 3,
            ValueFromPipeline = true,
            Mandatory = false,
            HelpMessage = "Traces to visualize: Excel,Xperf,Mpi")]
        public String What
        {
            get { return what; }
            set { what = value; }
        }

        private List<Dwarf> dwarflist;

        protected override void BeginProcessing()
        {
            dwarflist = new List<Dwarf>();
        }

        protected override void ProcessRecord()
        {
            if (dwarf == null)
                throw new Exception("RUN-DWARF-ERROR: Null-object passed as input.");

            dwarflist.Add((Dwarf)dwarf);
        }

        private static bool ExcelCleared = false;

        protected override void EndProcessing()
        {
            foreach (Dwarf d in dwarflist.ToArray())
            {
                //if (reset != 0)
                //{
                //    ExcelWriter.CleanXlsValues(resultsfilename);
                //    this.WriteVerbose("PLOT-DWARF: Results.xlsx cleared.");


                //    //if (reset == 2)
                //    //{
                //    //    //HelperMethods.DeleteFilesInDirectory(d.profiledir, "*.*");
                //    //    //HelperMethods.DeleteFilesInDirectory(d.resultdir, "*.*");
                //    //    HelperMethods.DeleteFile(d.profilefile);
                //    //    HelperMethods.DeleteFile(d.resultfile);
                //    //    HelperMethods.DeleteFile(d.xperftracefile);
                //    //    HelperMethods.DeleteFile(d.mpitracefile);
                //    //}
                //    //this.WriteObject(dwarf);
                //    //return;
                //}



                if (d.success)
                {

                    if (what.Equals("Excel"))
                    {
                        if (!ExcelCleared)
                        {
                            //string resultfilename = System.Environment.GetEnvironmentVariable("DWARF_BENCH");
                            //resultfilename += "\\Results\\Results.xlsx";
                            ExcelWriter.CleanXlsValues(ResultsFile);
                            ExcelCleared = true;
                        }

                        if (String.IsNullOrEmpty(ResultsFile))
                            throw new Exception("PLOT-DWARF-ERROR: Excel results file not specified.");

                        this.WriteVerbose("PLOT-DWARF: Writing results to Excel file " + resultsfilename + " for " + d.dwarfname +
                            "[" + d.platform + "," + d.parallel + "," + d.size + "]" + ".");

                        ExcelWriter.WriteLogToExcelFile(
                            resultsfilename,
                            d.internalname.ToString(),
                            d.platform,
                            d.parallel,
                            d.size,
                            d.time);

                        this.WriteVerbose("PLOT-DWARF: Done.");
                        //this.WriteObject(d);
                    }


                    if (what.Equals("Xperf"))
                    {
                        if (d.xperftrace)
                        {

                            this.WriteVerbose("PLOT-DWARF: Opening Xperfview for " + d.dwarfname +
                                "[" + d.platform + "," + d.parallel + "," + d.size + "]" + ".");

                            HelperMethods.StartXperfView(dwarf.xperftracefile);

                            this.WriteVerbose("PLOT-DWARF: Done.");
                        }
                        else
                            Console.WriteLine("Skipping Xperfview as xperf tracing was not enabled.");
                    }
                    
                    if (what.Equals("JumpShot"))
                    {
                        if (d.parallel == parallel.mpi)
                        {
                            if (d.mpitrace)
                            {
                                this.WriteVerbose("PLOT-DWARF: Opening Jumpshot MPI trace analysis for " + d.dwarfname +
                                    "[" + d.platform + "," + d.parallel + "," + d.size + "]" + ".");


                                //Process tracing information 
                                string sdkpath = System.Environment.GetEnvironmentVariable("CCP_SDK");
                                string mpicsync = sdkpath + "Bin\\mpicsync.exe "; //"%CCP_SDK%Bin\\mpicsync.exe ";
                                string etl2clog = System.Environment.GetEnvironmentVariable("JUMPSHOT_DIR") + "\\etl2clog.exe"; //"%CCP_SDK%Bin\\etl2otf.exe ";
                                string etlsource = d.mpitracefile;

                                //create cloc sync data (OBSOLOETE)
                                this.WriteVerbose("PLOT-DWARF: Creating clock-sync data: " + mpicsync + etlsource);
                                HelperMethods.ExecCommand(mpicsync, etlsource, true);

                                //Convert etl 2 otf
                                this.WriteVerbose("PLOT-DWARF: Converting etl to clog: " + etl2clog + etlsource);
                                HelperMethods.ExecCommand(etl2clog, etlsource, true);

                                //Convert clog2 to slog2
                                string jumpshotdir = System.Environment.GetEnvironmentVariable("JUMPSHOT_DIR");
                                string clog2slog = jumpshotdir + "\\clog2TOslog2.jar";
                                string jumpshot = jumpshotdir + "\\jumpshot.jar";

                                string clog2file = etlsource.Replace(".etl", ".etl.clog2");
                                string slog2file = clog2file.Replace(".clog2", ".slog2");

                                string javapath = System.Environment.GetEnvironmentVariable("JAVA_BIN");
                                string javabin = javapath + "\\java.exe";

                                this.WriteVerbose("PLOT-DWARF: Converting clog2 to slog2: " + clog2file);
                                HelperMethods.ExecCommand(javabin, " -jar " + clog2slog + " " + clog2file, true);

                                this.WriteVerbose("PLOT-DWARF: Opening Jumoshot for " + slog2file);
                                HelperMethods.ExecCommand(javabin, " -jar " + jumpshot + " " + slog2file, false);

                                this.WriteVerbose("PLOT-DWARF: Done.");
                                //this.WriteObject(d);
                            }
                            else
                                Console.WriteLine("Skipping JumpShot as mpi tracing was not enabled.");
                        }
                    }

                    if (what.Equals("Vampir"))
                    {
                        if (d.parallel == parallel.mpi)
                        {
                            if (d.mpitrace)
                            {
                                this.WriteVerbose("PLOT-DWARF: Opening Vampir MPI trace analysis for " + d.dwarfname +
                                    "[" + d.platform + "," + d.parallel + "," + d.size + "]" + ".");


                                //Process tracing information 
                                string sdkpath = System.Environment.GetEnvironmentVariable("CCP_SDK");
                                string mpicsync = sdkpath + "Bin\\mpicsync.exe "; //"%CCP_SDK%Bin\\mpicsync.exe ";
                                string etl2otf = System.Environment.GetEnvironmentVariable("JUMPSHOT_DIR") + "\\etl2otf.exe"; //"%CCP_SDK%Bin\\etl2otf.exe ";
                                string etlsource = d.mpitracefile;

                                this.WriteVerbose("PLOT-DWARF: Creating clock-sync data: " + mpicsync + etlsource);
                                HelperMethods.ExecCommand(mpicsync, etlsource, true);

                                //Convert etl2otf
                                this.WriteVerbose("PLOT-DWARF: Converting etl to otf: " + etl2otf + etlsource);
                                HelperMethods.ExecCommand(etl2otf, etlsource, true);

                                //Convert clog2 to slog2
                                string jumpshotdir = System.Environment.GetEnvironmentVariable("JUMPSHOT_DIR");
                                string vampirbin = jumpshotdir + "\\vampir.exe";

                                string otffile = etlsource.Replace(".etl", ".etl_otf.otf");
                                this.WriteVerbose("PLOT-DWARF: Opening Vampir for " + otffile);
                                HelperMethods.ExecCommand(vampirbin, otffile, false);

                                this.WriteVerbose("PLOT-DWARF: Done.");
                                //this.WriteObject(d);
                            }
                            else
                                Console.WriteLine("Skipping Vampir as mpi tracing was not enabled.");
                        }
                    }
                }
                else
                {
                    string _msg = "PLOT-DWARF: Skipping results plot for " +
                        d.internalname +
                        "(platform:" + d.platform +
                        ", parallel:" + d.parallel +
                        ", size:" + d.size +
                        "), because it did not execute correctly.";
                    this.WriteVerbose(_msg);

                }
                this.WriteObject(d);
            }
        }
    }
}
